﻿using Microsoft.Win32;
using movie.tool.library.hash;
using movie.tool.library.ui;
using movie.tool.module.film.model;
using movie.tool.module.film.service;
using movie.tool.module.http;
using System.Collections.ObjectModel;
using System.IO;
using System.Windows;
using System.ComponentModel;
using System;

namespace movie.tool.module.film.ui
{
    /// <summary>
    /// MovieScenesControl.xaml 的交互逻辑
    /// </summary>
    public partial class MovieScenesControl : BaseControl
    {
        public static readonly DependencyProperty ConfigProperty = DependencyProperty.Register("Config", typeof(MovieProject), typeof(MovieScenesControl));
        public MovieProject Config
        {
            get => (MovieProject)GetValue(ConfigProperty);
            set => SetValue(ConfigProperty, value);
        }

        public static readonly DependencyProperty BusyInfoProperty = DependencyProperty.Register("BusyInfo", typeof(BusyInfo), typeof(MovieScenesControl));
        public BusyInfo BusyInfo
        {
            get => (BusyInfo)GetValue(BusyInfoProperty);
            set => SetValue(BusyInfoProperty, value);
        }

        private SceneConfig currentScene;

        public SceneConfig CurrentScene
        {
            get => currentScene;
            set
            {
                if(currentScene != null)
                {
                    currentScene.PropertyChanged -= CurrentScenePropertyChanged;
                }
                currentScene = value;
                if(currentScene != null)
                {
                    currentScene.PropertyChanged += CurrentScenePropertyChanged;
                }
                SendPropertyChanged(nameof(CurrentScene));
            }
        }

        private void CurrentScenePropertyChanged(object? sender, PropertyChangedEventArgs e)
        {
            if (CurrentScene != null && object.Equals(e.PropertyName, nameof(CurrentScene.Sequence)))
            {
                Config.ResortScene();
            }
        }
        /// <summary>
        /// 添加、删除和保存的按钮是否可见
        /// </summary>
        public Visibility ModifyVisible
        {
            get
            {
                if(Config != null && Config.ImportProject)
                {
                    return Visibility.Collapsed;
                }
                return Visibility.Visible;
            }
        }

        private ObservableCollection<PlayMode> playModes;
        public ObservableCollection<PlayMode> PlayModes
        {
            get => playModes;
            set
            {
                playModes = value;
                SendPropertyChanged(nameof(PlayModes));
            }
        }

        public MovieScenesControl()
        {
            InitializeComponent();
            PlayModes = new ObservableCollection<PlayMode>();
            PlayModes.Add(new PlayMode(1, "循环播放"));
            PlayModes.Add(new PlayMode(2, "顺序播放"));
            PlayModes.Add(new PlayMode(3, "单次播放"));
            PlayModes.Add(new PlayMode(4, "投影第一组线索并循环播放"));
        }

        private async void AddSceneClick(object sender, RoutedEventArgs e)
        {
            if (Config.Scenes == null)
            {
                Config.Scenes = new ObservableCollection<SceneConfig>();
            }
            SceneConfig sc = new SceneConfig();
            if (Config.Scenes.Count > 0)
            {
                sc.Sequence = Config.Scenes[Config.Scenes.Count - 1].Sequence + 1;
            }
            else
            {
                sc.Sequence = 1;
            }
            sc.PlayMode = 1;
            sc.Name = "新加剧幕";
            long? id = await MovieClient.SaveScene(sc, Config.Id);
            if (id is not null and > 0)
            {
                sc.Id = (long)id;
                Config.Scenes.Add(sc);
                CurrentScene = sc;
            }
            MovieService.SaveProjectMovie(Config);
        }

        private async void DeleteSceneClick(object sender, RoutedEventArgs e)
        {
            if (CurrentScene == null)
            {
                MessageBox.Show("请选择一个剧幕");
                return;
            }
            bool result = await HttpInvoker.DeleteAsync("movieserver/movieScenes/" + CurrentScene.Id);
            if (result)
            {
                Config.Scenes.Remove(CurrentScene);
                MovieService.SaveProjectMovie(Config);
                MessageBox.Show("删除成功");
            }
        }

        private void SceneBrowserClick(object sender, RoutedEventArgs e)
        {
            if (CurrentScene == null)
            {
                MessageBox.Show("请选择一个剧幕再操作");
                return;
            }
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.Filter = "视频文件(*.mp4)|*.mp4";
            dialog.Title = "选择剧幕文件";
            if (CurrentScene != null && !string.IsNullOrEmpty(CurrentScene.File))
            {
                string filePath = Path.Join(MovieService.ProjectJsonFilePath(Config.Id), CurrentScene.File);
                dialog.InitialDirectory = Path.GetDirectoryName(filePath);
            }

            bool? result = dialog.ShowDialog();
            if (result != null && result == true)
            {
                string rootPath = MovieService.ProjectJsonFilePath(Config.Id);
                if (dialog.FileName.StartsWith(rootPath))
                {
                    //选择的文件在项目目录下,那就不用复制了
                    CurrentScene.File = Path.GetRelativePath(rootPath, dialog.FileName);
                }
                else
                {
                    string path = Path.Combine(rootPath, "scene");
                    if (!Directory.Exists(path))
                    {
                        Directory.CreateDirectory(path);
                    }
                    path = Path.Combine(path, Path.GetFileName(dialog.FileName));
                    if (File.Exists(path))
                    {
                        string selectDigest = SHA1Hash.FileDigest(dialog.FileName);
                        string targetDigest = SHA1Hash.FileDigest(path);
                        if (!selectDigest.Equals(targetDigest))
                        {
                            MessageBox.Show("文件" + path + "已经存在,无法复制,请选择不同名称的文件");
                            return;
                        }
                        else
                        {
                            //相同,不需要复制
                            CurrentScene.File = Path.GetRelativePath(rootPath, path);
                        }
                    }
                    else
                    {
                        File.Copy(dialog.FileName, path);
                        CurrentScene.File = Path.GetRelativePath(rootPath, path);
                    }
                }
                //如果剧幕是默认名称,那改为文件名
                if ("新加剧幕".Equals(CurrentScene.Name))
                {
                    string name = Path.GetFileNameWithoutExtension(CurrentScene.File);
                    string sceneName = CurrentScene.Name;
                    int sequence = CurrentScene.Sequence;
                    MovieService.SceneNameAndSequence(name, ref sceneName, ref sequence);
                    CurrentScene.Name = sceneName;
                    if(CurrentScene.Sequence != sequence)
                    {
                        CurrentScene.Sequence = sequence;
                        Config.ResortScene();
                    }
                }
            }
        }
        private async void MovieSceneSubmitClick(object sender, RoutedEventArgs e)
        {
            if (BusyInfo.Busy || CurrentScene == null)
            {
                return;
            }
            try
            {
                BusyInfo.Busy = true;
                BusyInfo.BusyMessage = "正在保存剧幕信息...";
                bool result = await MovieClient.UpdateScene(CurrentScene);
                if (result)
                {
                    //查看文件是否修改
                    if (!string.IsNullOrEmpty(CurrentScene.File))
                    {
                        string rootPath = MovieService.ProjectJsonFilePath(Config.Id);
                        string filePath = Path.Join(rootPath, CurrentScene.File);

                        if (File.Exists(filePath))
                        {
                            string digest = await MovieClient.SceneFileDigest(CurrentScene.Id);
                            string localDigest = SHA1Hash.FileDigest(filePath);
                            if (!localDigest.Equals(digest))
                            {
                                //文件不一样,那上传文件
                                BusyInfo.BusyMessage = "剧幕信息保存成功,正在上传文件...";
                                //文件不一样,那上传文件，先Obs上传
                                FileDigestParam param = new FileDigestParam();
                                param.Sha1 = localDigest;
                                param.FileName = Path.GetFileName(filePath);
                                param.Path = CurrentScene.File;
                                bool res = await MovieClient.UploadSceneFileObs(filePath, CurrentScene.Id, param);
                                if (!res)
                                {
                                    // 再偿试从服务端上传
                                    res = await MovieClient.UploadSceneFile(filePath, CurrentScene.Id);
                                }
                                if (res)
                                {
                                    MessageBox.Show("提交成功");
                                }
                                else
                                {
                                    MessageBox.Show("剧幕信息保存成功,文件上传失败");
                                }
                            }
                            else
                            {
                                MessageBox.Show("提交成功");
                            }
                        }
                        else
                        {
                            MessageBox.Show("提交成功");
                        }
                    }
                    else
                    {
                        MessageBox.Show("提交成功");
                    }
                }
            }
            catch(Exception ex)
            {
                MessageBox.Show("提交失败:" + ex.Message);
            }
            finally
            {
                BusyInfo.Reset();
            }
        }

        private void BaseControl_Loaded(object sender, RoutedEventArgs e)
        {
            SendPropertyChanged(nameof(ModifyVisible));
        }

        private async void SceneDownloadClick(object sender, RoutedEventArgs e)
        {
            if (BusyInfo.Busy || CurrentScene == null)
            {
                return;
            }
            try
            {
                BusyInfo.Busy = true;
                string rootPath = MovieService.ProjectJsonFilePath(Config.Id);
                MovieSynchronizer synchronizer = new MovieSynchronizer(BusyInfo, Config.Id);
                await synchronizer.SyncScene(rootPath, CurrentScene);
            }
            finally
            {
                BusyInfo.Reset();
            }
        }

        private async void ResetSceneSequenceClick(object sender, RoutedEventArgs e)
        {
            if (BusyInfo.Busy || Config==null || Config.Scenes == null || Config.Scenes.Count == 0)
            {
                return;
            }
            try
            {
                BusyInfo.Busy = true;
                for(int i = 1; i <= Config.Scenes.Count; ++i)
                {
                    SceneConfig sc = Config.Scenes[i-1];
                    if (i == sc.Sequence)
                    {
                        continue;
                    }
                    int old = sc.Sequence;
                    sc.Sequence = i;
                    bool ret = await MovieClient.UpdateScene(sc);
                    if (!ret)
                    {
                        sc.Sequence = old; //没有成功修改,那改回原来的值
                    }
                }
            }
            finally
            {
                BusyInfo.Reset();
            }
        }
    }
}
